﻿// <summary>
using System;
using System.IO;
using System.Threading;
using UnityEditor;
using UnityEngine;
/// 自定义的编辑器窗口
/// </summary>
public class ScenePackWindow : EditorWindow
{

    string ToolsUseDescribe = "本工具用与快速方便地对场景进行打包,使用方法为:\r\n\r\n选中模型--->勾选需要演示的各个平台--->点击 开始打包 --->点击 上传服务器"; 
    bool IsCreateAndroidAB = false;  
    bool IsCreateIosAB = false;    
    bool IsCreateHololensAB = false;    
    bool IsCreatePCAB = false;
    bool IsCreateSDF = false;
    public static string titleName = "MarsDT 场景打包工具V 1.0";
    bool IsUploadEnable = false;
    bool IsSelectGo = false;
    string HelpStr = "请先选择一个要打包的对象";
    bool IsShowHelpLabl = true;
    bool IsPack = false;

    private  GUIStyle style_label;//样式类
    private GUIStyle style_margin;
    private GUIStyle style_18font;
    private GUIStyle style_16font;
    private Texture texture;
    public static ScenePackWindow spw;

    public string assetsBundlePath;
    public string assetsBundleRootName="AssetBundles2";

    public bool isCheckPlatform = false;
    public string sceneName = "";//打包的场景名字，默认为选择中的第一个GameObject的名字
    private  void InitStyle(){
        //按需设置样式
        style_label = new GUIStyle(GUI.skin.label);
        style_label.margin.top = 5;
        style_label.margin.left = 5;
        style_label.fontSize = 16;
       // style_label.normal.textColor = new Color(232, 232, 232, 1);
       // style_label.fontStyle = FontStyle.Normal;
        style_margin = new GUIStyle(GUI.skin.label);
        style_margin.margin.left=50;

        style_18font = new GUIStyle(GUI.skin.label);
        style_18font.fontSize = 18;
        style_16font = new GUIStyle(GUI.skin.label);
        style_16font.fontSize = 16;
        
    }

    public void Awake()
    {
        texture = Resources.Load("testicon") as Texture;
        
    }

    [MenuItem("场景打包工具/打开打包界面")]
    public static void ShowWindow()
    {  
        spw= (ScenePackWindow)EditorWindow.GetWindow(typeof(ScenePackWindow) , true, titleName);
        spw.Show();
        spw.Focus();
        
    }
    void CheckPlatformAndGameObject()
    {
        IsPack = false;
        if (IsCreateAndroidAB || IsCreateIosAB || IsCreateHololensAB || IsCreatePCAB)
        {
            isCheckPlatform = true;
        }
        else
        {  
            isCheckPlatform = false;  
        }
        
        if (isCheckPlatform && IsSelectGo)
        {
            IsPack = true;
            IsShowHelpLabl = false;
        }
        else if (isCheckPlatform)
        {
            IsShowHelpLabl = true;
            HelpStr = "请至少选择一个需要打包的模型";
        }
        else {
            IsShowHelpLabl = true;
            HelpStr = "至少选择一个支持的平台";
        }
        
    }
    void OnGUI()
    {
        CheckPlatformAndGameObject();
        InitStyle();
        EditorGUILayout.Space();
        //texture=EditorGUILayout.ObjectField("", texture, typeof(Texture), true) as Texture;
        // 文本
        GUILayout.Label(ToolsUseDescribe, style_label, GUILayout.Width(600));
        EditorGUILayout.BeginVertical();
        EditorGUILayout.Space();
        EditorGUILayout.Space();

        //IsCreateSDF = EditorGUILayout.ToggleLeft("生成场景描述文件", IsCreateSDF , style_16font, GUILayout.Width(180), GUILayout.Height(20));
        EditorGUILayout.Space();
        EditorGUILayout.Space();
        GUILayout.Label("支持的设备包括:", style_18font, GUILayout.Width(200f));
        GUILayout.BeginArea(new Rect(150,130, 200, 100));
        IsCreateAndroidAB = EditorGUILayout.ToggleLeft("Android(安卓设备)", IsCreateAndroidAB, style_16font, GUILayout.Width(180), GUILayout.Height(20));
        IsCreateIosAB = EditorGUILayout.ToggleLeft("IOS(苹果设备)", IsCreateIosAB, style_16font, GUILayout.Width(180), GUILayout.Height(20));
        IsCreateHololensAB = EditorGUILayout.ToggleLeft("Hololens(全息设备)", IsCreateHololensAB, style_16font, GUILayout.Width(180), GUILayout.Height(20));
        IsCreatePCAB = EditorGUILayout.ToggleLeft("PC(电脑设备)", IsCreatePCAB, style_16font, GUILayout.Width(180), GUILayout.Height(20));
        GUILayout.EndArea();
        EditorGUILayout.EndVertical();
        EditorGUILayout.BeginVertical();
        GUILayout.Label("", GUILayout.Height(100));
        sceneName=EditorGUILayout.TextField("输入场景名字： ", sceneName,GUILayout.Width(300),GUILayout.Height(30));
        EditorGUI.BeginDisabledGroup(!IsPack);
      
        
        if (GUILayout.Button("开始打包", GUILayout.Width(150f), GUILayout.Height(40f)))
        {
            ClearConsole();
            //Debug.Log("开始打包："+ Selection.gameObjects.Length);
            string newABRoot = assetsBundlePath+"/" + sceneName;
            Debug.Log("当前打包的场景路径:"+ newABRoot);
            //在Assets/AssetBundles/ 下创建当前场景名字的文件夹
            if (!Directory.Exists(newABRoot))
            {
                AssetDatabase.CreateFolder("Assets/"+assetsBundleRootName, sceneName); 
            }
            CreateSDF.ExportSDFJsonDataWithRootPath(newABRoot, sceneName);

            PackScenes(newABRoot, sceneName);
        }
        EditorGUI.EndDisabledGroup();
        EditorGUI.BeginDisabledGroup(!IsUploadEnable);
        EditorGUILayout.Space();
        if (GUILayout.Button("上传服务器", GUILayout.Width(150f),GUILayout.Height(40f)))
        {
            
            Debug.Log("开始上传服务器！");
        }
        EditorGUILayout.Space();
        EditorGUI.EndDisabledGroup();
        if (!IsPack)
        {
            EditorGUILayout.Space();
            EditorGUILayout.Space();

            EditorGUILayout.HelpBox(HelpStr, MessageType.Warning);  //显示帮助框，类型为 警告  
        }
        EditorGUILayout.EndVertical();
    }
    void OnInspectorUpdate()//实时刷新面板
    {
        //这里开启窗口的重绘，不然窗口信息不会刷新
        this.Repaint();
    }
    void OnFocus()
    {
        //Debug.Log("当窗口获得焦点时调用一次");
        assetsBundlePath = Application.dataPath + "/"+ assetsBundleRootName;
        //Debug.Log(assetsBundlePath);
        if (!Directory.Exists(assetsBundlePath))
        {
            Directory.CreateDirectory(assetsBundlePath);
            Debug.Log("AB包根目录不存在,重新创建: " + assetsBundlePath);
            AssetDatabase.Refresh();
        }
        UpdateCheckObject();
    }
    void OnSelectionChange()
    {
        UpdateCheckObject();
    }
    void UpdateCheckObject()
    {
        //当窗口出去开启状态，并且在Hierarchy视图中选择某游戏对象时调用
        if (Selection.gameObjects.Length > 0 )
        {
            //CreateSDF.ClearConsole();
            //Debug.Log("已选中" + Selection.gameObjects[0].name + "可以开始打包了");
            sceneName = Selection.gameObjects[0].name;
            IsSelectGo = true;
        }
        else
        {
            IsSelectGo = false;
        }
    }
    public void PackScenes(string pathRoot,string sceneNameP)
    {
        GameObject[] goList = Selection.gameObjects;
        int abSize = goList.Length;
        string[] path = new string[abSize];
        for (int i = 0; i < abSize; i++)
        {
            path[i] = AssetDatabase.GetAssetPath(goList[i]);
        }
        AssetBundleBuild[] abba = new AssetBundleBuild[1];
        abba[0].assetBundleName = sceneNameP + ".aba.srf";
        abba[0].assetNames = new string[abSize];
        for (int i = 0; i < abSize; i++)
        {
            abba[0].assetNames[i] = path[i];
        }
        AssetBundleBuild[] abbi = new AssetBundleBuild[1];
        abbi[0].assetBundleName = sceneNameP + ".abi.srf";
        abbi[0].assetNames = new string[abSize];
        for (int i = 0; i < abSize; i++)
        {
            abbi[0].assetNames[i] = path[i];
        }
        AssetBundleBuild[] abbh = new AssetBundleBuild[1];
        abbh[0].assetBundleName = sceneNameP + ".abh.srf";
        abbh[0].assetNames = new string[abSize];
        for (int i = 0; i < abSize; i++)
        {
            abbh[0].assetNames[i] = path[i];
        }
        AssetBundleBuild[] abbw = new AssetBundleBuild[1];
        abbw[0].assetBundleName = sceneNameP + ".abw.srf";
        abbw[0].assetNames = new string[abSize];
        for (int i = 0; i < abSize; i++)
        {
            abbw[0].assetNames[i] = path[i];
        }
        DateTime startTime = DateTime.Now;
        DateTime beginTime = DateTime.Now;
        if (IsCreatePCAB)
        {
            beginTime = DateTime.Now;
            Debug.Log("PC平台资源包打包开始,Time:" + beginTime);
            BuildPipeline.BuildAssetBundles(pathRoot, abbw, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows);
            Debug.Log("PC平台资源包打包完成,耗时: " + (DateTime.Now - beginTime).Seconds + " 秒");
        }


        if (IsCreateHololensAB)
        {
            beginTime = DateTime.Now;
            Debug.Log("Holo平台资源包打包开始,Time:" + beginTime);
            BuildPipeline.BuildAssetBundles(pathRoot, abbh, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.WSAPlayer);
            Debug.Log("Holo平台资源包打包完成,耗时: " + (DateTime.Now - beginTime).Seconds + " 秒");
        }
        if (IsCreateAndroidAB)
        {
            beginTime = DateTime.Now;
            Debug.Log("Android平台资源包打包开始,Time:" + beginTime);
            BuildPipeline.BuildAssetBundles(pathRoot, abba, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.Android);
            Debug.Log("Android平台资源包打包完成,耗时: " + (DateTime.Now - beginTime).Seconds+" 秒");
        }
        if (IsCreateIosAB)
        {
            beginTime = DateTime.Now;
            Debug.Log("IOS平台资源包打包开始,Time:" + beginTime);
            BuildPipeline.BuildAssetBundles(pathRoot, abbi, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.iOS);
            Debug.Log("IOS平台资源包打包完成,耗时: " + (DateTime.Now - beginTime).Seconds + " 秒");
        }
        File.Delete(pathRoot +"/"+ sceneNameP);
        string[] fileArray = Directory.GetFiles(pathRoot);
        for (int i = 0; i < fileArray.Length; i++)
        {
            if (fileArray[i].Contains(".manifest"))
            {
                File.Delete(fileArray[i]);
                //Debug.Log("删除无用文件："+ fileArray[i]);
            }
        }
        
        AssetDatabase.Refresh();
        //打开一个通知栏
        string showText = "场景：" + sceneNameP + " 打包完成,总共耗时:" + (DateTime.Now - startTime).Seconds+ " 秒";
        this.ShowNotification(new GUIContent(showText));
        Debug.Log(showText);
        //Thread.Sleep(3000);
        try
        {
            System.Diagnostics.Process.Start(@pathRoot);
        }
        catch (Exception e)
        {
            Debug.LogError(e.Message + "  " + @pathRoot);
        }
        
    }

    public static void ClearConsole()
    {
        //清空控制台Log信息--------------------------------------------------------------------------
        var logEntries = System.Type.GetType("UnityEditorInternal.LogEntries,UnityEditor.dll");
        var clearMethod = logEntries.GetMethod("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
        clearMethod.Invoke(null, null);
        //-------------------------------------------------------------------------------------------
    }

}